This document aims at exploring the dataset of 4 individuals in 2018. For that purpose, we need first to load the weanlingNES package to load data.
For convenience, we aggregate all 4 individuals into one dataset.
Some explanatory plots
Missing values
# build dataset to check for missing values
dataPlot <- melt(data_2018[, .(.id, is.na(.SD)), .SDcol = -c(
".id",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"date",
"phase",
"lat",
"lon"
)])
# add the id of rows
dataPlot[, id_row := c(1:.N), by = c("variable", ".id")]
# plot
ggplot(dataPlot, aes(x = variable, y = id_row, fill = value)) +
geom_tile() +
labs(x = "Attributes", y = "Rows") +
scale_fill_manual(
values = c("white", "black"),
labels = c("Real", "Missing")
) +
facet_wrap(.id ~ ., scales = "free_y") +
theme_jjo() +
theme(
legend.position = "top",
axis.text.x = element_text(angle = 45, hjust = 1),
legend.key = element_rect(colour = "black")
)
So far so good, only few variables seems to have missing values:
# table with percent
table_inter <- data_2018[, lapply(.SD, function(x) {
round(length(x[is.na(x)]) * 100 / length(x), 1)
}), .SDcol = -c(
".id",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"date",
"phase",
"lat",
"lon"
)]
# find which are different from 0
cond_inter <- sapply(table_inter, function(x) {
x == 0
})
# display the percentages that are over 0
table_inter[, which(cond_inter) := NULL] %>%
sable(caption = "Percentage of missing values per columns having missing values!") %>%
scroll_box(width = "100%")
Table 3: Percentage of missing values per columns having missing values!
|
lightatsurf
|
lattenuation
|
euphoticdepth
|
thermoclinedepth
|
driftrate
|
benthicdivevertrate
|
cornerindex
|
foragingindex
|
verticalspeed90perc
|
verticalspeed95perc
|
dist_dep
|
temp
|
ssh
|
psu
|
vel
|
|
26.3
|
89
|
62.6
|
1.3
|
0.5
|
22.7
|
75.8
|
0.5
|
0.1
|
0.1
|
35.1
|
35.1
|
35.1
|
35.1
|
35.1
|
Outliers
Ok, let’s have a look at all the data. But first, we have to remove outliers. Some of them are quiet easy to spot looking at the distribution of dive duration:
Before
ggplot(
data_2018[, .SD][, state := "Before"],
aes(x = dduration, fill = .id)
) +
geom_histogram(show.legend = FALSE) +
geom_vline(xintercept = 3000, linetype = "longdash") +
facet_grid(state ~ .id,
scales = "free"
) +
labs(y = "# of dives", x = "Dive duration (s)") +
theme_jjo()
After
ggplot(
data_2018[dduration < 3000, ][][, state := "After"],
aes(x = dduration, fill = .id)
) +
geom_histogram(show.legend = FALSE) +
geom_vline(xintercept = 3000, linetype = "longdash") +
facet_grid(state ~ .id,
scales = "free"
) +
labs(x = "# of dives", y = "Dive duration (s)") +
theme_jjo()
It seems much better, so let’s remove any rows with dduration > 3000 sec.
# filter data
data_2018_filter <- data_2018[dduration < 3000, ]
# nbrow removed
data_2018[dduration >= 3000, .(nb_row_removed = .N), by = .id] %>%
sable(caption = "# of rows removed by 2018-individuals")
Table 4: # of rows removed by 2018-individuals
|
.id
|
nb_row_removed
|
|
ind_2018070
|
3
|
|
ind_2018072
|
1
|
|
ind_2018074
|
33
|
Check day and night
Light levels
# let's first average `lightatsurf` by individuals, day since departure and hour
dataPlot <- data_2018[, .(lightatsurf = median(lightatsurf)),
by = .(.id, day_departure, date = as.Date(date), hour)
]
# display the result
ggplot(dataPlot, aes(x = day_departure, y = hour, fill = lightatsurf)) +
geom_tile() +
facet_grid(.id ~ .) +
theme_jjo() +
labs(x = "# of days since departure",
y = "Hour",
fill = "Light level at the surface")+
theme(legend.position = c("bottom"))
Day and night detection
# let's first average `lightatsurf` by individuals, day since departure and hour
dataPlot <- data_2018[, .(lightatsurf = median(lightatsurf)),
by = .(.id,
day_departure,
date = as.Date(date),
hour,
phase)
]
# display the result
ggplot(dataPlot, aes(x = day_departure, y = hour, fill = phase)) +
geom_tile() +
facet_grid(.id ~ .) +
theme_jjo() +
labs(x = "# of days since departure",
y = "Hour",
fill = "Day time and night time as detected by the `cal_phase_day` function") +
theme(legend.position = c("bottom"))
All Variables
names_display <- names(data_2018_filter[, -c(
".id",
"date",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"euphoticdepth",
"thermoclinedepth",
"day_departure",
"phase",
"lat",
"lon",
"dist_dep"
)])
# calulate the median of driftrate for each day
median_driftrate <- data_2018[divetype == "2: drift",
.(driftrate = quantile(driftrate, 0.5)),
by = .(date = as.Date(date), .id)
]
# let's identity when the smooth changes sign
changes_driftrate <- median_driftrate %>%
.[, .(
y_smooth = predict(loess(driftrate ~ as.numeric(date), span = 0.25)),
date
), by = .id] %>%
.[c(FALSE, diff(sign(y_smooth)) != 0), ]
for (i in names_display) {
cat("#####", i, "{.unlisted .unnumbered} \n")
if (i == "maxdepth") {
print(
ggplot() +
geom_point(
data = data_2018_filter[, .(
.id,
date,
thermoclinedepth
)],
aes(
x = as.Date(date),
y = -thermoclinedepth,
colour = "Thermocline (m)"
),
alpha = .2,
size = .5
) +
geom_point(
data = data_2018_filter[, .(
.id,
date,
euphoticdepth
)],
aes(
x = as.Date(date),
y = -euphoticdepth,
colour = "Euphotic (m)"
),
alpha = .2,
size = .5
) +
scale_colour_manual(
values = c(
"Thermocline (m)" = "red",
"Euphotic (m)" = "black"
),
name = "Zone"
) +
new_scale_color() +
geom_point(
data = melt(data_2018_filter[, .(.id, date, get(i))],
id.vars = c(".id", "date")
),
aes(
x = as.Date(date),
y = -value,
col = .id
),
alpha = 1 / 10,
size = .5,
show.legend = FALSE
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = "Maximum Depth (m)") +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
))
cat("<blockquote> Considering `ind_2018074` has slightly different values than other individuals for the thermocline depth, it would be interesting to see where the animal went. </blockquote>")
} else if (i == "driftrate") {
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i), divetype)],
id.vars = c(".id", "date", "divetype")),
aes(
x = as.Date(date),
y = value,
col = divetype
)
) +
geom_point(
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = "Drift Rate 'm/s", col = "Dive Type") +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
) +
guides(colour = guide_legend(override.aes = list(
size = 7,
alpha = 1
)))
)
} else {
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i))],
id.vars = c(".id", "date")),
aes(
x = as.Date(date),
y = value,
col = .id
)
) +
geom_point(
show.legend = FALSE,
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
geom_vline(data = dataVline, aes(xintercept = as.Date(date)), colour = "black", linetype=2) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = i) +
theme_jjo() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
)
}
cat("\n \n")
}
The vertical dashed lines represent changes in buoyancy (see vignette("buoyancy_detect") for more information)
maxdepth
Considering ind_2018074 has slightly different values than other individuals for the thermocline depth, it would be interesting to see where the animal went.
dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

temp

ssh

psu

vel

Few questions, that I should look into it:
- is the bimodal distribution of
dduration, desctime due to nycthemeral migration?
- is the bimodal distribution of
descrate (especially for ind2018070 and ind_2018072) due to drift dive?
- is
lightatbott could be used to identify bioluminescence, cause it seems there is a lot going on at the bottom?
- are the variations observed for
lightatsurf is due to moon cycle?
- not sure why is there a bimodal distribution of
tempatbott!
drifrate that one is awesome! Thanks to divetype we can clearly see a pattern of how driftrate (and so buoyancy) change according time.
- the bimodal distribution of
verticalspeed90 and verticalspeed95 should be due to drift dive.
# same plot with a colored for the phase of the day
for (i in names_display) {
cat("####", i, "{-} \n")
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i), phase)],
id.vars = c(
".id",
"date",
"phase"
)
),
aes(
x = as.Date(date),
y = value,
col = phase
)
) +
geom_point(
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = i) +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
) +
guides(colour = guide_legend(override.aes = list(
size = 7,
alpha = 1
)))
)
cat("\n \n")
}
The vertical dashed lines represent changes in buoyancy (see vignette("buoyancy_detect") for more information)
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

temp

ssh

psu

vel

All Variables during the first month
for (i in names_display) {
cat("####", i, "{.unlisted .unnumbered} \n")
if (i == "maxdepth") {
print(
ggplot() +
geom_point(
data = data_2018_filter[day_departure < 32, .(
.id,
day_departure,
thermoclinedepth
)],
aes(
x = day_departure,
y = -thermoclinedepth,
colour = "Thermocline (m)",
group = day_departure
),
alpha = .2,
size = .5
) +
geom_point(
data = data_2018_filter[day_departure < 32, .(
.id,
day_departure,
euphoticdepth
)],
aes(
x = day_departure,
y = -euphoticdepth,
colour = "Euphotic (m)",
group = day_departure
),
alpha = .2,
size = .5
) +
scale_colour_manual(
values = c(
"Thermocline (m)" = "red",
"Euphotic (m)" = "black"
),
name = "Zone"
) +
new_scale_color() +
geom_boxplot(
data = melt(data_2018_filter[day_departure < 32,
.(.id, day_departure, get(i))],
id.vars = c(".id", "day_departure")),
aes(
x = day_departure,
y = -value,
col = .id,
group = day_departure
),
alpha = 1 / 10,
size = .5,
show.legend = FALSE
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = "Maximum Depth (m)") +
theme_jjo() +
theme(legend.position = "bottom")
)
} else {
print(
ggplot(
data = melt(data_2018_filter[day_departure < 32,
.(.id, day_departure, get(i))],
id.vars = c(".id", "day_departure")),
aes(
x = day_departure,
y = value,
color = .id,
group = day_departure
)
) +
geom_boxplot(
show.legend = FALSE,
alpha = 1 / 10,
size = .5
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = i) +
theme_jjo()
)
}
cat("\n \n")
}
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

temp

ssh

psu

vel

for (i in names_display) {
cat("####", i, "{.unlisted .unnumbered} \n")
print(
ggplot(
data = melt(data_2018_filter[
day_departure < 32,
.(.id, day_departure, get(i), phase)
],
id.vars = c(".id", "day_departure", "phase")
),
aes(
x = day_departure,
y = value,
color = phase,
group = interaction(day_departure, phase),
)
) +
geom_boxplot(
alpha = 1 / 10,
size = .5
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = i) +
theme_jjo() +
theme(legend.position = "bottom")
)
cat("\n \n")
}
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

temp

ssh

psu

vel

Correlation
Can we find nice correlation?
# compute correlation
corr_2018 <- round(cor(data_2018_filter[, names_display, with = F],
use = "pairwise.complete.obs"
), 1)
# replace NA value by 0
corr_2018[is.na(corr_2018)] <- 0
# compute p_values
corr_p_2018 <- cor_pmat(data_2018_filter[, names_display, with = F])
# replace NA value by 0
corr_p_2018[is.na(corr_p_2018)] <- 1
# display
ggcorrplot(
corr_2018,
p.mat = corr_p_2018,
hc.order = TRUE,
method = "circle",
type = "lower",
ggtheme = theme_jjo(),
sig.level = 0.05,
colors = c("#00AFBB", "#E7B800", "#FC4E07")
)
Another way to see it:
# flatten correlation matrix
cor_result_2018 <- flat_cor_mat(corr_2018, corr_p_2018)
# keep only the one above .7
cor_result_2018[cor >= .7, ][order(-abs(cor))] %>%
sable(caption = "Pairwise correlation above 0.75 and associated p-values")
Table 5: Pairwise correlation above 0.75 and associated p-values
|
row
|
column
|
cor
|
p
|
|
verticalspeed90perc
|
verticalspeed95perc
|
1.0
|
0
|
|
tempatsurf
|
temp
|
0.9
|
0
|
|
maxdepth
|
asctime
|
0.8
|
0
|
|
botttime
|
efficiency
|
0.8
|
0
|
|
dwigglesbott
|
foragingindex
|
0.8
|
0
|
|
maxdepth
|
dduration
|
0.7
|
0
|
|
maxdepth
|
desctime
|
0.7
|
0
|
|
dduration
|
desctime
|
0.7
|
0
|
|
dduration
|
asctime
|
0.7
|
0
|
|
totvertdistbot
|
bottrange
|
0.7
|
0
|
|
totvertdistbot
|
verticalspeed90perc
|
0.7
|
0
|
|
totvertdistbot
|
verticalspeed95perc
|
0.7
|
0
|
I guess nothing unexpected here, I’ll have to check with Patrick about the efficiency ;)
Drift Rate
In the following graphs:
driftrate is calculated using only divetype == "2: drift"
- whereas all the others variables are calculated all dives considered
# build dataset
dataPlot <- data_2018_filter[divetype == "2: drift",
# median drift rate for drift dive
.(driftrate = median(driftrate, na.rm = T)),
by = .(.id, day_departure)
][data_2018_filter[,
.(
# median dive duration all dives considered
dduration = median(dduration, na.rm = T),
# median max depth all dives considered
maxdepth = median(maxdepth, na.rm = T),
# median bottom dives all dives considered
botttime = median(botttime, na.rm = T)
),
by = .(.id, day_departure)
],
on = c(".id", "day_departure")
]
# plot
ggplot(dataPlot, aes(x = botttime, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
scale_x_continuous(limits = c(0, 700)) +
labs(x = "Daily median Bottom time (s)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
# plot
ggplot(dataPlot, aes(x = maxdepth, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
labs(x = "Daily median Maximum depth (m)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
# plot
ggplot(dataPlot, aes(x = dduration, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
labs(x = "Daily median Dive duration (s)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
Behavioral Aerobic Dive Limit (bADL)
# dive duration vs pdi by days
ggplot(data = data_2018_filter[pdi < 300, ], aes(
x = dduration,
y = pdi,
color = .id,
group = dduration,
fill = "none"
)) +
geom_boxplot(show.legend = FALSE, outlier.alpha = 0.05, alpha = 0) +
labs(x = "Dive duration (s)", y = "Post-dive duration (s)") +
facet_wrap(. ~ .id, scales = "free_x") +
theme_jjo()
# dive duration vs pdi by days
ggplot(data = data_2018_filter[pdi < 300,], aes(x = dduration,
y = pdi,
color = .id)) +
geom_point(show.legend = FALSE, alpha = 0.05) +
geom_smooth(
method = "gam",
show.legend = FALSE,
col = "black",
linetype = "dashed"
) +
labs(x = "Dive duration (s)", y = "Post-dive duration (s)") +
facet_wrap(. ~ .id, scales = "free_x") +
theme_jjo()
# dive duration vs pdi by days
ggplot(
data = data_2018_filter[pdi < 300, .(.id, pdi_ratio = pdi / dduration, day_departure)],
aes(
x = day_departure,
y = pdi_ratio,
color = .id,
group = day_departure,
fill = "none"
)
) +
geom_boxplot(show.legend = FALSE,
outlier.alpha = 0.05,
alpha = 0) +
labs(x = "# days since departure", y = "Post-dive / Dive duration ratio") +
facet_wrap(. ~ .id, scales = "free_x") +
# zoom
coord_cartesian(ylim = c(0, 0.4)) +
theme_jjo()
Based on Shero et al. (2018), we decided to look at the bADL as the 95th percentile of dive duration each day, for those with \(n \geq 50\). This threshold was chosen following this figure:
ggplot(data_2018_filter[,.(nb_dives = .N),
by = .(.id, day_departure)],
aes(x=nb_dives, fill=.id)) +
geom_histogram(show.legend = FALSE) +
facet_grid(.~.id) +
labs(y="# of days", x = "# of dives per day") +
theme_jjo()
# select day that have at least 50 dives
days_to_keep = data_2018_filter[,
.(nb_dives = .N),
by = .(.id, day_departure)] %>%
.[nb_dives >= 50,]
# keep only those days
data_2018_filter_complete_day = merge(data_2018_filter,
days_to_keep,
by = c(".id", "day_departure"))
# data plot
dataPlot = data_2018_filter_complete_day[divetype=="1: foraging",
.(badl = quantile(dduration, 0.95)),
by = .(.id, day_departure)]
# combine two datasets to be able to use a second axis
# https://stackoverflow.com/questions/49185583/two-y-axes-with-different-scales-for-two-datasets-in-ggplot2
dataMegaPlot = rbind(data_2018_filter_complete_day[divetype == "2: drift"] %>%
.[, .(w = .id,
y = driftrate,
x = day_departure,
z = "second_plot")],
dataPlot[, .(
w = .id,
# tricky one
y = (badl / 1000) - 1,
x = day_departure,
z = "first_plot"
)])
# plot
ggplot() +
geom_point(
data = dataMegaPlot[z == "second_plot", ],
aes(x = x, y = y),
alpha = 1 / 10,
size = 0.5,
color = "grey40",
show.legend = FALSE
) +
geom_path(data = dataMegaPlot[z == "first_plot", ],
aes(x = x, y = y, color = w),
show.legend = FALSE) +
scale_y_continuous(
# Features of the first axis
name = "Drift rate (m/s)",
# Add a second axis and specify its features
sec.axis = sec_axis( ~ (. * 1000) + 1000,
name = "Behavioral Aerobic Dive Limit (s)")
) +
labs(x = "# days since departure") +
facet_wrap(w ~ .) +
theme_jjo()
Looking at this graph, I want to believe that there is some kind of relationship between the bADL as defined by Shero et al. (2018) and the drift rate (and so buyoancy).
# get badl
dataplot_1 = data_2018_filter_complete_day[,
.(badl = quantile(dduration, 0.95)),
by = .(.id, day_departure)]
# get driftrate
dataplot_2 = data_2018_filter_complete_day[divetype == "2: drift",
.(driftrate = median(driftrate)),
by = .(.id, day_departure)]
# merge
dataPlot = merge(dataplot_1,
dataplot_2,
by = c(".id", "day_departure"),
all = TRUE)
# plot
ggplot(data = dataPlot, aes(x = badl, y = driftrate, col = .id)) +
geom_point(show.legend = FALSE) +
facet_wrap(.id~., scales = "free") +
theme_jjo()

ind_2018070
# ind_2018070
plot_ly(
x = dataPlot[.id == "ind_2018070", badl],
y = dataPlot[.id == "ind_2018070", day_departure],
z = dataPlot[.id == "ind_2018070", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018070", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018072
# ind_2018072
plot_ly(
x = dataPlot[.id == "ind_2018072", badl],
y = dataPlot[.id == "ind_2018072", day_departure],
z = dataPlot[.id == "ind_2018072", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018072", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018074
# ind_2018074
plot_ly(
x = dataPlot[.id == "ind_2018074", badl],
y = dataPlot[.id == "ind_2018074", day_departure],
z = dataPlot[.id == "ind_2018074", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018074", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018072
# ind_2018080
plot_ly(
x = dataPlot[.id == "ind_2018080", badl],
y = dataPlot[.id == "ind_2018080", day_departure],
z = dataPlot[.id == "ind_2018080", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018080", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
LS0tCnRpdGxlOiAiRGF0YSBFeHBsb3JhdGlvbiAtIDIwMTgiCmF1dGhvcjogIkpvZmZyZXkgSk9VTUFBIgpkYXRlOiAiYHIgaW52aXNpYmxlKFN5cy5zZXRsb2NhbGUobG9jYWxlID0gJ0MnKSk7IGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAnJUIgJWQsICVZJylgIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY3NzOiBjb3Ntb19jdXN0b20uY3NzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDogZGVmYXVsdAogICAgZmlnX2NhcHRpb246IHllcwogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHllcwogICAgICBzbW9vdGhfc2Nyb2xsOiBubwp2aWduZXR0ZTogPgogICVcVmlnbmV0dGVJbmRleEVudHJ5e0RhdGEgRXhwbG9yYXRpb24gLSAyMDE4fQogICVcVmlnbmV0dGVFbmdpbmV7a25pdHI6OnJtYXJrZG93bn0KICAlXFZpZ25ldHRlRW5jb2Rpbmd7VVRGLTh9Ci0tLQogIApgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBjb21tYW5kIHRvIGJ1aWxkIHBhY2thZ2Ugd2l0aG91dCBnZXR0aW5nIHZpZ25ldHRlIGVycm9yCiMgaHR0cHM6Ly9naXRodWIuY29tL3JzdHVkaW8vcmVudi9pc3N1ZXMvODMzCiMgZGV2dG9vbHM6OmNoZWNrKGJ1aWxkX2FyZ3M9YygiLS1uby1idWlsZC12aWduZXR0ZXMiKSkKCiMgcmVkdWNlIHBuZyBzaXplCmtuaXRyOjprbml0X2hvb2tzJHNldChvcHRpcG5nID0ga25pdHI6Omhvb2tfb3B0aXBuZykKa25pdHI6OmtuaXRfaG9va3Mkc2V0KHBuZ3F1YW50ID0ga25pdHI6Omhvb2tfcG5ncXVhbnQpCgojIGdsb2JhbCBvcHRpb24gcmVsYXRpdmUgdG8gcm1hcmtkb3duCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBvdXQud2lkdGggPSAiMTAwJSIsCiAgbWVzc2FnZSA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICAjIHRpZHkgPSBUUlVFLAogIGNhY2hlLmxhenkgPSBGQUxTRSwKICBvcHRpcG5nID0gIi1vNyAtcXVpZXQiLAogIHBuZ3F1YW50ID0gIi0tc3BlZWQ9MSIKKQoKIyBsaWJyYXJ5CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShndHN1bW1hcnkpICMgaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2d0c3VtbWFyeS92aWduZXR0ZXMvdGJsX3N1bW1hcnkuaHRtbApsaWJyYXJ5KGNvcnJwbG90KQpsaWJyYXJ5KGdnY29ycnBsb3QpCmxpYnJhcnkoZ2duZXdzY2FsZSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShEVCkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2Vvc3BoZXJlKQpsaWJyYXJ5KHRpZHluYykKbGlicmFyeShnZ2FuaW1hdGUpCmxpYnJhcnkodHJhbnNmb3JtcikKbGlicmFyeShtYWdpY2spCmxpYnJhcnkoZ2lmc2tpKQoKIyByZW1vdmUgc29tZSB3YXJuaW5ncwpzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkoZ2dwbG90MikpCgojIGRlZmluZSBteSBvd24gdGFibGUgZm9ybWF0OiBodHRwczovL2dpdGh1Yi5jb20vaGFvemh1MjMzL2thYmxlRXh0cmEvaXNzdWVzLzM3NApzYWJsZSA8LSBmdW5jdGlvbih4LCBlc2NhcGUgPSBULCAuLi4pIHsKICBrbml0cjo6a2FibGUoeCwgZXNjYXBlID0gZXNjYXBlLCAuLi4pICU+JQogICAga2FibGVfc3R5bGluZygKICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgInJlc3BvbnNpdmUiKSwKICAgICAgZnVsbF93aWR0aCA9IEYKICAgICkKfQoKIyB0aGVtZSBnZ3Bsb3QKIyBiYXNlZDogaHR0cHM6Ly9iZW5qYW1pbmxvdWlzLXN0YXQuZnIvZW4vYmxvZy8yMDIwLTA1LTIxLWFzdHVjZXMtZ2dwbG90LXJtYXJrZG93bi8KdGhlbWVfampvIDwtIGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDEyKSB7CiAgdGhlbWVfYncoYmFzZV9zaXplID0gYmFzZV9zaXplKSAlK3JlcGxhY2UlCiAgICB0aGVtZSgKICAgICAgIyB0aGUgd2hvbGUgZmlndXJlCiAgICAgICMgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDEpLCBmYWNlID0gImJvbGQiLCBtYXJnaW4gPSBtYXJnaW4oMCwwLDUsMCksIGhqdXN0ID0gMCksCiAgICAgICMgZmlndXJlIGFyZWEKICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAjIGF4ZXMKICAgICAgIyBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMC44NSksIGZhY2UgPSAiYm9sZCIpLAogICAgICAjIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuNzApLCBmYWNlID0gImJvbGQiKSwKICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gImJsYWNrIiwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMiwgImxpbmVzIiksIHR5cGUgPSAiY2xvc2VkIikpLAogICAgICAjIGxlZ2VuZAogICAgICAjIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuODUpLCBmYWNlID0gImJvbGQiKSwKICAgICAgIyBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuNzApLCBmYWNlID0gImJvbGQiKSwKICAgICAgIyBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksCiAgICAgICMgbGVnZW5kLmtleS5zaXplID0gdW5pdCgxLjUsICJsaW5lcyIpLAogICAgICAjIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksCiAgICAgICMgTGVzIDxVKzAwRTk+dGlxdWV0dGVzIGRhbnMgbGUgY2FzIGQndW4gZmFjZXR0aW5nCiAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjODg4ODg4IiwgY29sb3IgPSAiIzg4ODg4OCIpLAogICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMC44NSksIGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gIndoaXRlIiwgbWFyZ2luID0gbWFyZ2luKDUsIDAsIDUsIDApKQogICAgKQp9CmBgYAoKVGhpcyBkb2N1bWVudCBhaW1zIGF0IGV4cGxvcmluZyB0aGUgZGF0YXNldCBvZiA0IGluZGl2aWR1YWxzIGluIDIwMTguIEZvciB0aGF0IHB1cnBvc2UsIHdlIG5lZWQgZmlyc3QgdG8gbG9hZCB0aGUgYHdlYW5saW5nTkVTYCBwYWNrYWdlIHRvIGxvYWQgZGF0YS4KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xfQojIGxvYWQgbGlicmFyeQpsaWJyYXJ5KHdlYW5saW5nTkVTKQoKIyBsb2FkIGRhdGEKZGF0YSgiZGF0YV9uZXMiLCBwYWNrYWdlID0gIndlYW5saW5nTkVTIikKIyBsb2FkKCIuLi9kYXRhL2RhdGFfbmVzLnJkYSIpCmBgYAoKTGV04oCZcyBoYXZlIGEgbG9vayBhdCB3aGF04oCZcyBpbnNpZGUgYGRhdGFfbmVzJGRhdGFfMjAxOGA6CiAgCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yfQojIGxpc3Qgc3RydWN0dXJlCnN0cihkYXRhX25lcyR5ZWFyXzIwMTgsIG1heC5sZXZlbCA9IDEsIGdpdmUuYXR0ciA9IEYsIG5vLmxpc3QgPSBUKQpgYGAKCj4gQSBsaXN0IG9mIGByIGxlbmd0aChkYXRhX25lcyR5ZWFyXzIwMTgpYCBgZGF0YS5mcmFtZXNgLCBvbmUgZm9yIGVhY2ggc2VhbAoKRm9yIGNvbnZlbmllbmNlLCB3ZSBhZ2dyZWdhdGUgYWxsIGByIGxlbmd0aChkYXRhX25lcyR5ZWFyXzIwMTgpYCBpbmRpdmlkdWFscyBpbnRvIG9uZSBkYXRhc2V0LgoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTMsIGV2YWw9RkFMU0V9CiMgY29tYmluZSBhbGwgaW5kaXZpZHVhbHMKZGF0YV8yMDE4IDwtIHJiaW5kbGlzdChkYXRhX25lcyR5ZWFyXzIwMTgpCgojIGRpc3BsYXkKRFQ6OmRhdGF0YWJsZShkYXRhXzIwMThbc2FtcGxlLmludCguTiwgMTApLCBdLCBvcHRpb25zID0gbGlzdChzY3JvbGxYID0gVCkpCmBgYApgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNCwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CiMgY29tYmluZSBhbGwgaW5kaXZpZHVhbHMKZGF0YV8yMDE4IDwtIHJiaW5kbGlzdChkYXRhX25lcyR5ZWFyXzIwMTgpCgojIHRpdGxlCmNhdCgiPHRhYmxlIHN0eWxlPSd3aWR0aDogNTAlJz4iLCAKICAgIHBhc3RlMCgKICAgICAgIjxjYXB0aW9uPiIsIAogICAgICAiKCN0YWI6bXlEVGh0bWx0b29scykiLCAKICAgICAgIlNhbXBsZSBvZiAxMCByYW5kb20gcm93cyBmcm9tIGBkYXRhXzIwMThgIiwgCiAgICAgICI8L2NhcHRpb24+IiksIAogICAgIjwvdGFibGU+IiwgCiAgICBzZXAgPSAiXG4iKQoKIyBkaXNwbGF5CkRUOjpkYXRhdGFibGUoZGF0YV8yMDE4W3NhbXBsZS5pbnQoLk4sIDEwKSwgXSwgb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFQpKQpgYGAKCiMjIFN1bW1hcnkKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC01fQojIHJhd19kYXRhCmRhdGFfMjAxOFssIC4oCiAgbmJfZGF5c19yZWNvcmRlZCA9IHVuaXF1ZU4oYXMuRGF0ZShkYXRlKSksCiAgbmJfZGl2ZXMgPSAuTiwKICBtYXhkZXB0aF9tZWFuID0gbWVhbihtYXhkZXB0aCksCiAgZGR1cmF0aW9uX21lYW4gPSBtZWFuKGRkdXJhdGlvbiksCiAgYm90dHRpbWVfbWVhbiA9IG1lYW4oYm90dHRpbWUpLAogIHBkaV9tZWFuID0gbWVhbihwZGksIG5hLnJtID0gVCkKKSwgYnkgPSAuaWRdICU+JQogIHNhYmxlKAogICAgY2FwdGlvbiA9ICJTdW1tYXJ5IGRpdmluZyBpbmZvcm1hdGlvbiByZWxhdGl2ZSB0byBlYWNoIDIwMTggaW5kaXZpZHVhbCIsCiAgICBkaWdpdHMgPSAyCiAgKQpgYGAKPiBWZXJ5IG5pY2UgZGF0YXNldCA6KQoKIyMgU29tZSBleHBsYW5hdG9yeSBwbG90cwoKIyMjIE1pc3NpbmcgdmFsdWVzCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNiwgZmlnLmNhcD0iQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWUgaW4gMjAxOC1pbmRpdmlkdWFscyIsIGZpZy53aWR0aD05fQojIGJ1aWxkIGRhdGFzZXQgdG8gY2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzCmRhdGFQbG90IDwtIG1lbHQoZGF0YV8yMDE4WywgLiguaWQsIGlzLm5hKC5TRCkpLCAuU0Rjb2wgPSAtYygKICAiLmlkIiwKICAiZGl2ZW51bWJlciIsCiAgInllYXIiLAogICJtb250aCIsCiAgImRheSIsCiAgImhvdXIiLAogICJtaW4iLAogICJzZWMiLAogICJqdWxkYXRlIiwKICAiZGl2ZXR5cGUiLAogICJkYXRlIiwKICAicGhhc2UiLAogICJsYXQiLAogICJsb24iCildKQojIGFkZCB0aGUgaWQgb2Ygcm93cwpkYXRhUGxvdFssIGlkX3JvdyA6PSBjKDE6Lk4pLCBieSA9IGMoInZhcmlhYmxlIiwgIi5pZCIpXQoKIyBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IGlkX3JvdywgZmlsbCA9IHZhbHVlKSkgKwogIGdlb21fdGlsZSgpICsKICBsYWJzKHggPSAiQXR0cmlidXRlcyIsIHkgPSAiUm93cyIpICsKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoIndoaXRlIiwgImJsYWNrIiksCiAgICBsYWJlbHMgPSBjKCJSZWFsIiwgIk1pc3NpbmciKQogICkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLiwgc2NhbGVzID0gImZyZWVfeSIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIpCiAgKQpgYGAKClNvIGZhciBzbyBnb29kLCBvbmx5IGZldyB2YXJpYWJsZXMgc2VlbXMgdG8gaGF2ZSBtaXNzaW5nIHZhbHVlczoKICAKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTd9CiMgdGFibGUgd2l0aCBwZXJjZW50CnRhYmxlX2ludGVyIDwtIGRhdGFfMjAxOFssIGxhcHBseSguU0QsIGZ1bmN0aW9uKHgpIHsKICByb3VuZChsZW5ndGgoeFtpcy5uYSh4KV0pICogMTAwIC8gbGVuZ3RoKHgpLCAxKQp9KSwgLlNEY29sID0gLWMoCiAgIi5pZCIsCiAgImRpdmVudW1iZXIiLAogICJ5ZWFyIiwKICAibW9udGgiLAogICJkYXkiLAogICJob3VyIiwKICAibWluIiwKICAic2VjIiwKICAianVsZGF0ZSIsCiAgImRpdmV0eXBlIiwKICAiZGF0ZSIsCiAgInBoYXNlIiwKICAibGF0IiwKICAibG9uIgopXQoKIyBmaW5kIHdoaWNoIGFyZSBkaWZmZXJlbnQgZnJvbSAwCmNvbmRfaW50ZXIgPC0gc2FwcGx5KHRhYmxlX2ludGVyLCBmdW5jdGlvbih4KSB7CiAgeCA9PSAwCn0pCgojIGRpc3BsYXkgdGhlIHBlcmNlbnRhZ2VzIHRoYXQgYXJlIG92ZXIgMAp0YWJsZV9pbnRlclssIHdoaWNoKGNvbmRfaW50ZXIpIDo9IE5VTExdICU+JQogIHNhYmxlKGNhcHRpb24gPSAiUGVyY2VudGFnZSBvZiBtaXNzaW5nIHZhbHVlcyBwZXIgY29sdW1ucyBoYXZpbmcgbWlzc2luZyB2YWx1ZXMhIikgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIikKYGBgCgojIyMgT3V0bGllcnMgey50YWJzZXR9CgpPaywgbGV0J3MgaGF2ZSBhIGxvb2sgYXQgYWxsIHRoZSBkYXRhLiBCdXQgZmlyc3QsIHdlIGhhdmUgdG8gcmVtb3ZlIG91dGxpZXJzLiBTb21lIG9mIHRoZW0gYXJlIHF1aWV0IGVhc3kgdG8gc3BvdCBsb29raW5nIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZGl2ZSBkdXJhdGlvbjoKCiMjIyMgQmVmb3JlIHstfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTgsIGZpZy5jYXA9J0Rpc3RyaWJ1dGlvbiBvZiBgZGR1cmF0aW9uYCBmb3IgZWFjaCBzZWFsLiBUaGUgZGFzaGVkIGxpbmUgaGlnaGxpZ2h0IHRoZSAic3ViamVjdGl2ZSIgdGhyZXNob2xkIHVzZWQgdG8gcmVtb3ZlIG91dGxpZXJzICgzMDAwIHNlYyknLCBmaWcuaGVpZ2h0PTN9CmdncGxvdCgKICBkYXRhXzIwMThbLCAuU0RdWywgc3RhdGUgOj0gIkJlZm9yZSJdLAogIGFlcyh4ID0gZGR1cmF0aW9uLCBmaWxsID0gLmlkKQopICsKICBnZW9tX2hpc3RvZ3JhbShzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMzAwMCwgbGluZXR5cGUgPSAibG9uZ2Rhc2giKSArCiAgZmFjZXRfZ3JpZChzdGF0ZSB+IC5pZCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlIgogICkgKwogIGxhYnMoeSA9ICIjIG9mIGRpdmVzIiwgeCA9ICJEaXZlIGR1cmF0aW9uIChzKSIpICsKICB0aGVtZV9qam8oKQpgYGAKCiMjIyMgQWZ0ZXIgey19CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtOSwgZmlnLmNhcD0nU2FtZSBkaXN0cmlidXRpb24gb2YgYGRkdXJhdGlvbmAgZm9yIGVhY2ggc2VhbCBidXQgYWZ0ZXIgcmVtb3ZpbmcgYW55IGBkZHVyYXRpb25gID4gMzAwMCBzZWMuIFRoZSBkYXNoZWQgbGluZSBoaWdobGlnaHQgdGhlICJzdWJqZWN0aXZlIiB0aHJlc2hvbGQgdXNlZCB0byByZW1vdmUgb3V0bGllcnMnLCBmaWcuaGVpZ2h0PTN9CmdncGxvdCgKICBkYXRhXzIwMThbZGR1cmF0aW9uIDwgMzAwMCwgXVtdWywgc3RhdGUgOj0gIkFmdGVyIl0sCiAgYWVzKHggPSBkZHVyYXRpb24sIGZpbGwgPSAuaWQpCikgKwogIGdlb21faGlzdG9ncmFtKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzMDAwLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIpICsKICBmYWNldF9ncmlkKHN0YXRlIH4gLmlkLAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWUiCiAgKSArCiAgbGFicyh4ID0gIiMgb2YgZGl2ZXMiLCB5ID0gIkRpdmUgZHVyYXRpb24gKHMpIikgKwogIHRoZW1lX2pqbygpCmBgYAoKSXQgc2VlbXMgbXVjaCBiZXR0ZXIsIHNvIGxldCdzIHJlbW92ZSBhbnkgcm93cyB3aXRoIGBkZHVyYXRpb25gID4gMzAwMCBzZWMuCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTB9CiMgZmlsdGVyIGRhdGEKZGF0YV8yMDE4X2ZpbHRlciA8LSBkYXRhXzIwMThbZGR1cmF0aW9uIDwgMzAwMCwgXQoKIyBuYnJvdyByZW1vdmVkCmRhdGFfMjAxOFtkZHVyYXRpb24gPj0gMzAwMCwgLihuYl9yb3dfcmVtb3ZlZCA9IC5OKSwgYnkgPSAuaWRdICU+JQogIHNhYmxlKGNhcHRpb24gPSAiIyBvZiByb3dzIHJlbW92ZWQgYnkgMjAxOC1pbmRpdmlkdWFscyIpCmBgYAoKIyMjIENoZWNrIGRheSBhbmQgbmlnaHQgey50YWJzZXR9CgojIyMjIExpZ2h0IGxldmVscwoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTExLCBmaWcuY2FwPSJWaXN1YWxpemF0aW9uIG9mIGxpZ2h0IGxldmVsIGF0IHRoZSBzdXJmYWNlIGFsb25nIDIwMTgtaW5kaXZpZHVhbHMnIHRyaXAiLCBmaWcuaGVpZ2h0PTZ9CiMgbGV0J3MgZmlyc3QgYXZlcmFnZSBgbGlnaHRhdHN1cmZgIGJ5IGluZGl2aWR1YWxzLCBkYXkgc2luY2UgZGVwYXJ0dXJlIGFuZCBob3VyCmRhdGFQbG90IDwtIGRhdGFfMjAxOFssIC4obGlnaHRhdHN1cmYgPSBtZWRpYW4obGlnaHRhdHN1cmYpKSwKICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUsIGRhdGUgPSBhcy5EYXRlKGRhdGUpLCBob3VyKQpdCgojIGRpc3BsYXkgdGhlIHJlc3VsdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcyh4ID0gZGF5X2RlcGFydHVyZSwgeSA9IGhvdXIsIGZpbGwgPSBsaWdodGF0c3VyZikpICsKICBnZW9tX3RpbGUoKSArCiAgZmFjZXRfZ3JpZCguaWQgfiAuKSArCiAgdGhlbWVfampvKCkgKwogIGxhYnMoeCA9ICIjIG9mIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgCiAgICAgICB5ID0gIkhvdXIiLCAKICAgICAgIGZpbGwgPSAiTGlnaHQgbGV2ZWwgYXQgdGhlIHN1cmZhY2UiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKCJib3R0b20iKSkKYGBgCgojIyMjIERheSBhbmQgbmlnaHQgZGV0ZWN0aW9uCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTIsIGZpZy5jYXA9IlZpc3VhbGl6YXRpb24gb2YgZGV0ZWN0ZWQgbmlnaHQgdGltZSBhbmQgZGF5IHRpbWUgYWxvbmcgMjAxOC1pbmRpdmlkdWFscycgdHJpcCIsIGZpZy5oZWlnaHQ9Nn0KIyBsZXQncyBmaXJzdCBhdmVyYWdlIGBsaWdodGF0c3VyZmAgYnkgaW5kaXZpZHVhbHMsIGRheSBzaW5jZSBkZXBhcnR1cmUgYW5kIGhvdXIKZGF0YVBsb3QgPC0gZGF0YV8yMDE4WywgLihsaWdodGF0c3VyZiA9IG1lZGlhbihsaWdodGF0c3VyZikpLAogICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5X2RlcGFydHVyZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlKQpdCgojIGRpc3BsYXkgdGhlIHJlc3VsdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcyh4ID0gZGF5X2RlcGFydHVyZSwgeSA9IGhvdXIsIGZpbGwgPSBwaGFzZSkpICsKICBnZW9tX3RpbGUoKSArCiAgZmFjZXRfZ3JpZCguaWQgfiAuKSArCiAgdGhlbWVfampvKCkgKwogIGxhYnMoeCA9ICIjIG9mIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgCiAgICAgICB5ID0gIkhvdXIiLCAKICAgICAgIGZpbGwgPSAiRGF5IHRpbWUgYW5kIG5pZ2h0IHRpbWUgYXMgZGV0ZWN0ZWQgYnkgdGhlIGBjYWxfcGhhc2VfZGF5YCBmdW5jdGlvbiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKCJib3R0b20iKSkKYGBgCgojIyMgQWxsIFZhcmlhYmxlcyAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xM30KbmFtZXNfZGlzcGxheSA8LSBuYW1lcyhkYXRhXzIwMThfZmlsdGVyWywgLWMoCiAgIi5pZCIsCiAgImRhdGUiLAogICJkaXZlbnVtYmVyIiwKICAieWVhciIsCiAgIm1vbnRoIiwKICAiZGF5IiwKICAiaG91ciIsCiAgIm1pbiIsCiAgInNlYyIsCiAgImp1bGRhdGUiLAogICJkaXZldHlwZSIsCiAgImV1cGhvdGljZGVwdGgiLAogICJ0aGVybW9jbGluZWRlcHRoIiwKICAiZGF5X2RlcGFydHVyZSIsCiAgInBoYXNlIiwKICAibGF0IiwKICAibG9uIiwKICAiZGlzdF9kZXAiCildKQoKIyBjYWx1bGF0ZSB0aGUgbWVkaWFuIG9mIGRyaWZ0cmF0ZSBmb3IgZWFjaCBkYXkKbWVkaWFuX2RyaWZ0cmF0ZSA8LSBkYXRhXzIwMThbZGl2ZXR5cGUgPT0gIjI6IGRyaWZ0IiwKICAuKGRyaWZ0cmF0ZSA9IHF1YW50aWxlKGRyaWZ0cmF0ZSwgMC41KSksCiAgYnkgPSAuKGRhdGUgPSBhcy5EYXRlKGRhdGUpLCAuaWQpCl0KCiMgbGV0J3MgaWRlbnRpdHkgd2hlbiB0aGUgc21vb3RoIGNoYW5nZXMgc2lnbgpjaGFuZ2VzX2RyaWZ0cmF0ZSA8LSBtZWRpYW5fZHJpZnRyYXRlICU+JQogIC5bLCAuKAogICAgeV9zbW9vdGggPSBwcmVkaWN0KGxvZXNzKGRyaWZ0cmF0ZSB+IGFzLm51bWVyaWMoZGF0ZSksIHNwYW4gPSAwLjI1KSksCiAgICBkYXRlCiAgKSwgYnkgPSAuaWRdICU+JQogIC5bYyhGQUxTRSwgZGlmZihzaWduKHlfc21vb3RoKSkgIT0gMCksIF0KYGBgCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTQsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0KZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBpZiAoaSA9PSAibWF4ZGVwdGgiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlclssIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF0ZSwKICAgICAgICAgICAgdGhlcm1vY2xpbmVkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgICAgICB5ID0gLXRoZXJtb2NsaW5lZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJUaGVybW9jbGluZSAobSkiCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlclssIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF0ZSwKICAgICAgICAgICAgZXVwaG90aWNkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgICAgICB5ID0gLWV1cGhvdGljZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJFdXBob3RpYyAobSkiCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwoCiAgICAgICAgICB2YWx1ZXMgPSBjKAogICAgICAgICAgICAiVGhlcm1vY2xpbmUgKG0pIiA9ICJyZWQiLAogICAgICAgICAgICAiRXVwaG90aWMgKG0pIiA9ICJibGFjayIKICAgICAgICAgICksCiAgICAgICAgICBuYW1lID0gIlpvbmUiCiAgICAgICAgKSArCiAgICAgICAgbmV3X3NjYWxlX2NvbG9yKCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWywgLiguaWQsIGRhdGUsIGdldChpKSldLAogICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IGMoIi5pZCIsICJkYXRlIikKICAgICAgICAgICksCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgICAgICB5ID0gLXZhbHVlLAogICAgICAgICAgICBjb2wgPSAuaWQKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICAgIHNpemUgPSAuNSwKICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiTWF4aW11bSBEZXB0aCAobSkiKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iCiAgICAgICAgKSkKICAgIGNhdCgiPGJsb2NrcXVvdGU+IENvbnNpZGVyaW5nIGBpbmRfMjAxODA3NGAgaGFzIHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZXMgdGhhbiBvdGhlciBpbmRpdmlkdWFscyBmb3IgdGhlIHRoZXJtb2NsaW5lIGRlcHRoLCBpdCB3b3VsZCBiZSBpbnRlcmVzdGluZyB0byBzZWUgd2hlcmUgdGhlIGFuaW1hbCB3ZW50LiA8L2Jsb2NrcXVvdGU+IikKICB9IGVsc2UgaWYgKGkgPT0gImRyaWZ0cmF0ZSIpIHsKICAgIHByaW50KAogICAgICBnZ3Bsb3QoCiAgICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclssIC4oLmlkLCBkYXRlLCBnZXQoaSksIGRpdmV0eXBlKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIsICJkaXZldHlwZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbCA9IGRpdmV0eXBlCiAgICAgICAgKQogICAgICApICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiRHJpZnQgUmF0ZSAnbS9zIiwgY29sID0gIkRpdmUgVHlwZSIpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUoCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICAgICApICsKICAgICAgICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoCiAgICAgICAgICBzaXplID0gNywKICAgICAgICAgIGFscGhhID0gMQogICAgICAgICkpKQogICAgKQogIH0gZWxzZSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KAogICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbCA9IC5pZAogICAgICAgICkKICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGdlb21fdmxpbmUoCiAgICAgICAgICBkYXRhID0gY2hhbmdlc19kcmlmdHJhdGUsCiAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGRhdGUpLCAKICAgICAgICAgIGxpbmV0eXBlID0gMgogICAgICAgICkgKwogICAgICAgIGdlb21fdmxpbmUoZGF0YSA9IGRhdGFWbGluZSwgYWVzKHhpbnRlcmNlcHQgPSBhcy5EYXRlKGRhdGUpKSwgY29sb3VyID0gImJsYWNrIiwgbGluZXR5cGU9MikgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVtLyVZIikgKwogICAgICAgIGxhYnMoeCA9ICJEYXRlIiwgeSA9IGkpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKICAgICkKICB9CiAgCiAgY2F0KCJcbiBcbiIpCn0KYGBgCgpUaGUgdmVydGljYWwgZGFzaGVkIGxpbmVzIHJlcHJlc2VudCBjaGFuZ2VzIGluIGJ1b3lhbmN5IChzZWUgYHZpZ25ldHRlKCJidW95YW5jeV9kZXRlY3QiKWAgZm9yIG1vcmUgaW5mb3JtYXRpb24pCgojIyMgey51bmxpc3RlZCAudW5udW1iZXJlZCAudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTE1LCByZXN1bHRzPSdhc2lzJywgY2FjaGU9VFJVRSwgZWNobz1GQUxTRX0KZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMiLCBpLCAiey51bmxpc3RlZCAudW5udW1iZXJlZH0gXG4iKQogIGlmIChpID09ICJtYXhkZXB0aCIpIHsKICAgIHByaW50KAogICAgICBnZ3Bsb3QoKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyWywgLigKICAgICAgICAgICAgLmlkLAogICAgICAgICAgICBkYXRlLAogICAgICAgICAgICB0aGVybW9jbGluZWRlcHRoCiAgICAgICAgICApXSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICAgIHkgPSAtdGhlcm1vY2xpbmVkZXB0aCwKICAgICAgICAgICAgY29sb3VyID0gIlRoZXJtb2NsaW5lIChtKSIKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IC4yLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyWywgLigKICAgICAgICAgICAgLmlkLAogICAgICAgICAgICBkYXRlLAogICAgICAgICAgICBldXBob3RpY2RlcHRoCiAgICAgICAgICApXSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICAgIHkgPSAtZXVwaG90aWNkZXB0aCwKICAgICAgICAgICAgY29sb3VyID0gIkV1cGhvdGljIChtKSIKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IC4yLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCgKICAgICAgICAgIHZhbHVlcyA9IGMoCiAgICAgICAgICAgICJUaGVybW9jbGluZSAobSkiID0gInJlZCIsCiAgICAgICAgICAgICJFdXBob3RpYyAobSkiID0gImJsYWNrIgogICAgICAgICAgKSwKICAgICAgICAgIG5hbWUgPSAiWm9uZSIKICAgICAgICApICsKICAgICAgICBuZXdfc2NhbGVfY29sb3IoKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IGMoIi5pZCIsICJkYXRlIikpLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgICAgeSA9IC12YWx1ZSwKICAgICAgICAgICAgY29sID0gLmlkCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUsCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFCiAgICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJW0vJVkiKSArCiAgICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIk1heGltdW0gRGVwdGggKG0pIikgKwogICAgICAgIHRoZW1lX2pqbygpICsKICAgICAgICB0aGVtZSgKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICAgICAgICkKICAgICkKICAgIGNhdCgiPGJsb2NrcXVvdGU+IENvbnNpZGVyaW5nIGBpbmRfMjAxODA3NGAgaGFzIHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZXMgdGhhbiBvdGhlciBpbmRpdmlkdWFscyBmb3IgdGhlIHRoZXJtb2NsaW5lIGRlcHRoLCBpdCB3b3VsZCBiZSBpbnRlcmVzdGluZyB0byBzZWUgd2hlcmUgdGhlIGFuaW1hbCB3ZW50LiA8L2Jsb2NrcXVvdGU+IikKICB9IGVsc2UgaWYgKGkgPT0gImRyaWZ0cmF0ZSIpIHsKICAgIHByaW50KAogICAgICBnZ3Bsb3QoCiAgICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclssIC4oLmlkLCBkYXRlLCBnZXQoaSksIGRpdmV0eXBlKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIsICJkaXZldHlwZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbCA9IGRpdmV0eXBlCiAgICAgICAgKQogICAgICApICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiRHJpZnQgUmF0ZSAnbS9zIiwgY29sID0gIkRpdmUgVHlwZSIpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUoCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICAgICApICsKICAgICAgICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoCiAgICAgICAgICBzaXplID0gNywKICAgICAgICAgIGFscGhhID0gMQogICAgICAgICkpKQogICAgKQogIH0gZWxzZSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KAogICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbCA9IC5pZAogICAgICAgICkKICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGdlb21fdmxpbmUoCiAgICAgICAgICBkYXRhID0gY2hhbmdlc19kcmlmdHJhdGUsCiAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGRhdGUpLCAKICAgICAgICAgIGxpbmV0eXBlID0gMgogICAgICAgICkgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVtLyVZIikgKwogICAgICAgIGxhYnMoeCA9ICJEYXRlIiwgeSA9IGkpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKICAgICkKICB9CiAgCiAgY2F0KCJcbiBcbiIpCn0KYGBgCgojIyMgey51bmxpc3RlZCAudW5udW1iZXJlZH0KCj4gRmV3IHF1ZXN0aW9ucywgdGhhdCBJIHNob3VsZCBsb29rIGludG8gaXQ6CiAgPgogID4gKiBpcyB0aGUgYmltb2RhbCBkaXN0cmlidXRpb24gb2YgYGRkdXJhdGlvbmAsIGBkZXNjdGltZWAgZHVlIHRvIG55Y3RoZW1lcmFsIG1pZ3JhdGlvbj8KICA+ICogaXMgdGhlIGJpbW9kYWwgZGlzdHJpYnV0aW9uIG9mIGBkZXNjcmF0ZWAgKGVzcGVjaWFsbHkgZm9yIGBpbmQyMDE4MDcwYCBhbmQgYGluZF8yMDE4MDcyYCkgZHVlIHRvIGRyaWZ0IGRpdmU/CiAgPiAqIGlzIGBsaWdodGF0Ym90dGAgY291bGQgYmUgdXNlZCB0byBpZGVudGlmeSBiaW9sdW1pbmVzY2VuY2UsIGNhdXNlIGl0IHNlZW1zIHRoZXJlIGlzIGEgbG90IGdvaW5nIG9uIGF0IHRoZSBib3R0b20/CiAgPiAqIGFyZSB0aGUgdmFyaWF0aW9ucyBvYnNlcnZlZCBmb3IgYGxpZ2h0YXRzdXJmYCBpcyBkdWUgdG8gbW9vbiBjeWNsZT8KICA+ICogbm90IHN1cmUgd2h5IGlzIHRoZXJlIGEgYmltb2RhbCBkaXN0cmlidXRpb24gb2YgYHRlbXBhdGJvdHRgIQogID4gKiBgZHJpZnJhdGVgIHRoYXQgb25lIGlzIGF3ZXNvbWUhIFRoYW5rcyB0byBgZGl2ZXR5cGVgIHdlIGNhbiBjbGVhcmx5IHNlZSBhIHBhdHRlcm4gb2YgaG93IGRyaWZ0cmF0ZSAoYW5kIHNvIGJ1b3lhbmN5KSBjaGFuZ2UgYWNjb3JkaW5nIHRpbWUuCj4gKiB0aGUgYmltb2RhbCBkaXN0cmlidXRpb24gb2YgYHZlcnRpY2Fsc3BlZWQ5MGAgYW5kIGB2ZXJ0aWNhbHNwZWVkOTVgIHNob3VsZCBiZSBkdWUgdG8gZHJpZnQgZGl2ZS4KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xNiwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQojIHNhbWUgcGxvdCB3aXRoIGEgY29sb3JlZCBmb3IgdGhlIHBoYXNlIG9mIHRoZSBkYXkKZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMiLCBpLCAiey19IFxuIikKICBwcmludCgKICAgIGdncGxvdCgKICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclssIC4oLmlkLCBkYXRlLCBnZXQoaSksIHBoYXNlKV0sCiAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKAogICAgICAgICAgICAgICAgICAgICIuaWQiLAogICAgICAgICAgICAgICAgICAgICJkYXRlIiwKICAgICAgICAgICAgICAgICAgICAicGhhc2UiCiAgICAgICAgICAgICAgICAgICkKICAgICAgKSwKICAgICAgYWVzKAogICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICBjb2wgPSBwaGFzZQogICAgICApCiAgICApICsKICAgICAgZ2VvbV9wb2ludCgKICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICBzaXplID0gLjUKICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gaSkgKwogICAgICB0aGVtZV9qam8oKSArCiAgICAgIHRoZW1lKAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICAgKSArCiAgICAgIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdCgKICAgICAgICBzaXplID0gNywKICAgICAgICBhbHBoYSA9IDEKICAgICAgKSkpCiAgKQogIGNhdCgiXG4gXG4iKQp9CmBgYAoKVGhlIHZlcnRpY2FsIGRhc2hlZCBsaW5lcyByZXByZXNlbnQgY2hhbmdlcyBpbiBidW95YW5jeSAoc2VlIGB2aWduZXR0ZSgiYnVveWFuY3lfZGV0ZWN0IilgIGZvciBtb3JlIGluZm9ybWF0aW9uKQoKIyMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWQgLnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xNywgcmVzdWx0cz0nYXNpcycsIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CiMgc2FtZSBwbG90IHdpdGggYSBjb2xvcmVkIGZvciB0aGUgcGhhc2Ugb2YgdGhlIGRheQpmb3IgKGkgaW4gbmFtZXNfZGlzcGxheSkgewogIGNhdCgiIyMjIyIsIGksICJ7LX0gXG4iKQogIHByaW50KAogICAgZ2dwbG90KAogICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWywgLiguaWQsIGRhdGUsIGdldChpKSwgcGhhc2UpXSwKICAgICAgICAgICAgICAgICAgaWQudmFycyA9IGMoCiAgICAgICAgICAgICAgICAgICAgIi5pZCIsCiAgICAgICAgICAgICAgICAgICAgImRhdGUiLAogICAgICAgICAgICAgICAgICAgICJwaGFzZSIKICAgICAgICAgICAgICAgICAgKQogICAgICApLAogICAgICBhZXMoCiAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgeSA9IHZhbHVlLAogICAgICAgIGNvbCA9IHBoYXNlCiAgICAgICkKICAgICkgKwogICAgICBnZW9tX3BvaW50KAogICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgIHNpemUgPSAuNQogICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVtLyVZIikgKwogICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSBpKSArCiAgICAgIHRoZW1lX2pqbygpICsKICAgICAgdGhlbWUoCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICAgICApICsKICAgICAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KAogICAgICAgIHNpemUgPSA3LAogICAgICAgIGFscGhhID0gMQogICAgICApKSkKICApCiAgY2F0KCJcbiBcbiIpCn0KYGBgCgojIyMgQWxsIFZhcmlhYmxlcyBkdXJpbmcgdGhlIGZpcnN0IG1vbnRoCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTgsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0KZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMiLCBpLCAiey51bmxpc3RlZCAudW5udW1iZXJlZH0gXG4iKQogIGlmIChpID09ICJtYXhkZXB0aCIpIHsKICAgIHByaW50KAogICAgICBnZ3Bsb3QoKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgLigKICAgICAgICAgICAgLmlkLAogICAgICAgICAgICBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB0aGVybW9jbGluZWRlcHRoCiAgICAgICAgICApXSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIHkgPSAtdGhlcm1vY2xpbmVkZXB0aCwKICAgICAgICAgICAgY29sb3VyID0gIlRoZXJtb2NsaW5lIChtKSIsCiAgICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gLjIsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbZGF5X2RlcGFydHVyZSA8IDMyLCAuKAogICAgICAgICAgICAuaWQsCiAgICAgICAgICAgIGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIGV1cGhvdGljZGVwdGgKICAgICAgICAgICldLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgeSA9IC1ldXBob3RpY2RlcHRoLAogICAgICAgICAgICBjb2xvdXIgPSAiRXVwaG90aWMgKG0pIiwKICAgICAgICAgICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwoCiAgICAgICAgICB2YWx1ZXMgPSBjKAogICAgICAgICAgICAiVGhlcm1vY2xpbmUgKG0pIiA9ICJyZWQiLAogICAgICAgICAgICAiRXVwaG90aWMgKG0pIiA9ICJibGFjayIKICAgICAgICAgICksCiAgICAgICAgICBuYW1lID0gIlpvbmUiCiAgICAgICAgKSArCiAgICAgICAgbmV3X3NjYWxlX2NvbG9yKCkgKwogICAgICAgIGdlb21fYm94cGxvdCgKICAgICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbZGF5X2RlcGFydHVyZSA8IDMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLiguaWQsIGRheV9kZXBhcnR1cmUsIGdldChpKSldLCAKICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpKSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIHkgPSAtdmFsdWUsCiAgICAgICAgICAgIGNvbCA9IC5pZCwKICAgICAgICAgICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUsCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFCiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBsYWJzKHggPSAiIyBkYXlzIHNpbmNlIGRlcGFydHVyZSIsIHkgPSAiTWF4aW11bSBEZXB0aCAobSkiKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQogICAgKQogIH0gZWxzZSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KAogICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbZGF5X2RlcGFydHVyZSA8IDMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4oLmlkLCBkYXlfZGVwYXJ0dXJlLCBnZXQoaSkpXSwgCiAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IGMoIi5pZCIsICJkYXlfZGVwYXJ0dXJlIikpLAogICAgICAgIGFlcygKICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgeSA9IHZhbHVlLAogICAgICAgICAgY29sb3IgPSAuaWQsCiAgICAgICAgICBncm91cCA9IGRheV9kZXBhcnR1cmUKICAgICAgICApCiAgICAgICkgKwogICAgICAgIGdlb21fYm94cGxvdCgKICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgbGFicyh4ID0gIiMgZGF5cyBzaW5jZSBkZXBhcnR1cmUiLCB5ID0gaSkgKwogICAgICAgIHRoZW1lX2pqbygpCiAgICApCiAgfQogIGNhdCgiXG4gXG4iKQp9CmBgYAoKIyMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWQgLnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xOSwgcmVzdWx0cz0nYXNpcycsIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBpZiAoaSA9PSAibWF4ZGVwdGgiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlcltkYXlfZGVwYXJ0dXJlIDwgMzIsIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgdGhlcm1vY2xpbmVkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB5ID0gLXRoZXJtb2NsaW5lZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJUaGVybW9jbGluZSAobSkiLAogICAgICAgICAgICBncm91cCA9IGRheV9kZXBhcnR1cmUKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IC4yLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgLigKICAgICAgICAgICAgLmlkLAogICAgICAgICAgICBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICBldXBob3RpY2RlcHRoCiAgICAgICAgICApXSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIHkgPSAtZXVwaG90aWNkZXB0aCwKICAgICAgICAgICAgY29sb3VyID0gIkV1cGhvdGljIChtKSIsCiAgICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gLjIsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKAogICAgICAgICAgdmFsdWVzID0gYygKICAgICAgICAgICAgIlRoZXJtb2NsaW5lIChtKSIgPSAicmVkIiwKICAgICAgICAgICAgIkV1cGhvdGljIChtKSIgPSAiYmxhY2siCiAgICAgICAgICApLAogICAgICAgICAgbmFtZSA9ICJab25lIgogICAgICAgICkgKwogICAgICAgIG5ld19zY2FsZV9jb2xvcigpICsKICAgICAgICBnZW9tX2JveHBsb3QoCiAgICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4oLmlkLCBkYXlfZGVwYXJ0dXJlLCBnZXQoaSkpXSwgCiAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRheV9kZXBhcnR1cmUiKSksCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB5ID0gLXZhbHVlLAogICAgICAgICAgICBjb2wgPSAuaWQsCiAgICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41LAogICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRQogICAgICAgICkgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgbGFicyh4ID0gIiMgZGF5cyBzaW5jZSBkZXBhcnR1cmUiLCB5ID0gIk1heGltdW0gRGVwdGggKG0pIikgKwogICAgICAgIHRoZW1lX2pqbygpICsKICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKICAgICkKICB9IGVsc2UgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgKICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKC5pZCwgZGF5X2RlcGFydHVyZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbG9yID0gLmlkLAogICAgICAgICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlCiAgICAgICAgKQogICAgICApICsKICAgICAgICBnZW9tX2JveHBsb3QoCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9IGkpICsKICAgICAgICB0aGVtZV9qam8oKQogICAgKQogIH0KICBjYXQoIlxuIFxuIikKfQpgYGAKCiMjIyB7LnVubGlzdGVkIC51bm51bWJlcmVkfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTIwLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBwcmludCgKICAgIGdncGxvdCgKICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclsKICAgICAgICBkYXlfZGVwYXJ0dXJlIDwgMzIsCiAgICAgICAgLiguaWQsIGRheV9kZXBhcnR1cmUsIGdldChpKSwgcGhhc2UpCiAgICAgIF0sCiAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIsICJwaGFzZSIpCiAgICAgICksCiAgICAgIGFlcygKICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgY29sb3IgPSBwaGFzZSwKICAgICAgICBncm91cCA9IGludGVyYWN0aW9uKGRheV9kZXBhcnR1cmUsIHBoYXNlKSwKICAgICAgKQogICAgKSArCiAgICAgIGdlb21fYm94cGxvdCgKICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICBzaXplID0gLjUKICAgICAgKSArCiAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9IGkpICsKICAgICAgdGhlbWVfampvKCkgKwogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKICApCiAgY2F0KCJcbiBcbiIpCn0KYGBgCgojIyMgey51bmxpc3RlZCAudW5udW1iZXJlZCAudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTIxLCByZXN1bHRzPSdhc2lzJywgY2FjaGU9VFJVRSwgZWNobz1GQUxTRX0KZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMiLCBpLCAiey51bmxpc3RlZCAudW5udW1iZXJlZH0gXG4iKQogIHByaW50KAogICAgZ2dwbG90KAogICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWwogICAgICAgIGRheV9kZXBhcnR1cmUgPCAzMiwKICAgICAgICAuKC5pZCwgZGF5X2RlcGFydHVyZSwgZ2V0KGkpLCBwaGFzZSkKICAgICAgXSwKICAgICAgaWQudmFycyA9IGMoIi5pZCIsICJkYXlfZGVwYXJ0dXJlIiwgInBoYXNlIikKICAgICAgKSwKICAgICAgYWVzKAogICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICBjb2xvciA9IHBoYXNlLAogICAgICAgIGdyb3VwID0gaW50ZXJhY3Rpb24oZGF5X2RlcGFydHVyZSwgcGhhc2UpLAogICAgICApCiAgICApICsKICAgICAgZ2VvbV9ib3hwbG90KAogICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgIHNpemUgPSAuNQogICAgICApICsKICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgbGFicyh4ID0gIiMgZGF5cyBzaW5jZSBkZXBhcnR1cmUiLCB5ID0gaSkgKwogICAgICB0aGVtZV9qam8oKSArCiAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQogICkKICBjYXQoIlxuIFxuIikKfQpgYGAKCiMjIyBDb3JyZWxhdGlvbgoKQ2FuIHdlIGZpbmQgbmljZSBjb3JyZWxhdGlvbj8KICAKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTIyLCBmaWcuY2FwPSJDb3JyZWxhdGlvbiBtYXRyaXggKGNyb3NzZXMgaW5kaWNhdGUgbm9uIHNpZ25pZmljYW50IGNvcnJlbGF0aW9uKSIsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMH0KIyBjb21wdXRlIGNvcnJlbGF0aW9uCmNvcnJfMjAxOCA8LSByb3VuZChjb3IoZGF0YV8yMDE4X2ZpbHRlclssIG5hbWVzX2Rpc3BsYXksIHdpdGggPSBGXSwKICAgICAgICAgICAgICAgICAgICAgICB1c2UgPSAicGFpcndpc2UuY29tcGxldGUub2JzIgopLCAxKQoKIyByZXBsYWNlIE5BIHZhbHVlIGJ5IDAKY29ycl8yMDE4W2lzLm5hKGNvcnJfMjAxOCldIDwtIDAKCiMgY29tcHV0ZSBwX3ZhbHVlcwpjb3JyX3BfMjAxOCA8LSBjb3JfcG1hdChkYXRhXzIwMThfZmlsdGVyWywgbmFtZXNfZGlzcGxheSwgd2l0aCA9IEZdKQoKIyByZXBsYWNlIE5BIHZhbHVlIGJ5IDAKY29ycl9wXzIwMThbaXMubmEoY29ycl9wXzIwMTgpXSA8LSAxCgojIGRpc3BsYXkKZ2djb3JycGxvdCgKICBjb3JyXzIwMTgsCiAgcC5tYXQgPSBjb3JyX3BfMjAxOCwKICBoYy5vcmRlciA9IFRSVUUsCiAgbWV0aG9kID0gImNpcmNsZSIsCiAgdHlwZSA9ICJsb3dlciIsCiAgZ2d0aGVtZSA9IHRoZW1lX2pqbygpLAogIHNpZy5sZXZlbCA9IDAuMDUsCiAgY29sb3JzID0gIGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IikKKQpgYGAKCkFub3RoZXIgd2F5IHRvIHNlZSBpdDoKICAKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTIzfQojIGZsYXR0ZW4gY29ycmVsYXRpb24gbWF0cml4CmNvcl9yZXN1bHRfMjAxOCA8LSBmbGF0X2Nvcl9tYXQoY29ycl8yMDE4LCBjb3JyX3BfMjAxOCkKCiMga2VlcCBvbmx5IHRoZSBvbmUgYWJvdmUgLjcKY29yX3Jlc3VsdF8yMDE4W2NvciA+PSAuNywgXVtvcmRlcigtYWJzKGNvcikpXSAlPiUKICBzYWJsZShjYXB0aW9uID0gIlBhaXJ3aXNlIGNvcnJlbGF0aW9uIGFib3ZlIDAuNzUgYW5kIGFzc29jaWF0ZWQgcC12YWx1ZXMiKQpgYGAKCj4gSSBndWVzcyBub3RoaW5nIHVuZXhwZWN0ZWQgaGVyZSwgSSdsbCBoYXZlIHRvIGNoZWNrIHdpdGggUGF0cmljayBhYm91dCB0aGUgZWZmaWNpZW5jeSA7KQoKIyMgRGl2ZSBUeXBlCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMjQsIGZpZy5jYXA9IlByb3BvcnRpb24gZGl2ZSB0eXBlcyJ9CiMgZGF0YXNldCB0byBwbG90IHByb3BvcnRpb25hbCBhcmVhIHBsb3QKZGF0YV8yMDE4X2ZpbHRlclssIHN1bV9pZCA6PSAuTiwgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSldICU+JQogIC5bLCBzdW1faWRfZGF5cyA6PSAuTiwgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSwgZGl2ZXR5cGUpXSAlPiUKICAuWywgcHJvcCA6PSBzdW1faWRfZGF5cyAvIHN1bV9pZF0KZGF0YVBsb3QgPC0gdW5pcXVlKGRhdGFfMjAxOF9maWx0ZXJbLCAuKHByb3AsIC5pZCwgZGl2ZXR5cGUsIGRheV9kZXBhcnR1cmUpXSkKCiMgYXJlYSBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKAogIHggPSBhcy5udW1lcmljKGRheV9kZXBhcnR1cmUpLAogIHkgPSBwcm9wLAogIGZpbGwgPSBhcy5jaGFyYWN0ZXIoZGl2ZXR5cGUpCikpICsKICBnZW9tX2FyZWEoYWxwaGEgPSAwLjYsIHNpemUgPSAxKSArCiAgZmFjZXRfd3JhcCguaWQgfiAuLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBsYWJzKHggPSAiIyBvZiBkYXlzIHNpbmNlIGRlcGFydHVyZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIG9mIGRpdmVzIiwgCiAgICAgICBmaWxsID0gIkRpdmUgdHlwZXMiKQpgYGAKCiMjIERpdmUgZHVyYXRpb24gKnZzLiogTWF4aW11bSBkZXB0aCB7LnRhYnNldH0KCiMjIyBDb2xvcmVkIGJ5IElECgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMjUsIGZpZy5jYXA9IkRpdmUgZHVyYXRpb24gdnMuIE1heGltdW0gRGVwdGggY29sb3JlZCAyMDE4LWluZGl2aWR1YWxzIn0KIyBwbG90CmdncGxvdChkYXRhID0gZGF0YV8yMDE4X2ZpbHRlciwgYWVzKHkgPSBkZHVyYXRpb24sIHggPSBtYXhkZXB0aCwgY29sID0gLmlkKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IC41LCBhbHBoYSA9IC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCguaWQgfiAuKSArCiAgbGFicyh4ID0gIk1heGltdW0gZGVwdGggKG0pIiwgeSA9ICJEaXZlIGR1cmF0aW9uIChzKSIpICsKICB0aGVtZV9qam8oKQpgYGAKCiMjIyBDb2xvcmVkIGJ5IERpdmUgVHlwZQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI2LCBmaWcuY2FwPSJEaXZlIGR1cmF0aW9uIHZzLiBNYXhpbXVtIERlcHRoIGNvbG9yZWQgYnkgRGl2ZSBUeXBlIn0KIyBwbG90CmdncGxvdChkYXRhID0gZGF0YV8yMDE4X2ZpbHRlciwgYWVzKHkgPSBkZHVyYXRpb24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gbWF4ZGVwdGgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wgPSBkaXZldHlwZSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAuNSwgYWxwaGEgPSAuMSkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gNSwgYWxwaGEgPSAxKSkpICsKICBsYWJzKHggPSAiTWF4aW11bSBkZXB0aCAobSkiLCB5ID0gIkRpdmUgZHVyYXRpb24gKHMpIikgKwogIHRoZW1lX2pqbygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgojIyMgQ29sb3JlZCBieSAjIGRheXMgc2luY2UgZGVwYXJ0dXJlCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMjcsIGZpZy5jYXA9IkRpdmUgZHVyYXRpb24gdnMuIE1heGltdW0gRGVwdGggY29sb3JlZCBieSAjIGRheXMgc2luY2UgZGVwYXJ0dXJlIn0KIyBwbG90CmdncGxvdChkYXRhID0gZGF0YV8yMDE4X2ZpbHRlclssIHByb3BfdHJhY2sgOj0gKGRheV9kZXBhcnR1cmUgKiAxMDApIC8gbWF4KGRheV9kZXBhcnR1cmUpLCBieSA9IC5pZF0sIAogICAgICAgYWVzKHkgPSBkZHVyYXRpb24sIHggPSBtYXhkZXB0aCwgY29sID0gcHJvcF90cmFjaykpICsKICBnZW9tX3BvaW50KHNpemUgPSAuNSwgYWxwaGEgPSAuMSkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIGxhYnMoeCA9ICJNYXhpbXVtIGRlcHRoIChtKSIsIAogICAgICAgeSA9ICJEaXZlIGR1cmF0aW9uIChzKSIsIAogICAgICAgY29sID0gIlByb3BvcnRpb24gb2YgY29tcGxldGVkIHRyYWNrICglKSIpICsKICBzY2FsZV9jb2xvcl9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKIyMjIENvbG9yZWQgYnkgcGhhc2VzIG9mIGRheQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI4LCBmaWcuY2FwPSJEaXZlIGR1cmF0aW9uIHZzLiBNYXhpbXVtIERlcHRoIGNvbG9yZWQgYnkgcGhhc2VzIG9mIHRoZSBkYXkifQojIHBsb3QKZ2dwbG90KGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyLCBhZXMoeSA9IGRkdXJhdGlvbiwgeCA9IG1heGRlcHRoLCBjb2wgPSBwaGFzZSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAuNSwgYWxwaGEgPSAuMSkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gNSwgYWxwaGEgPSAxKSkpICsKICBsYWJzKHggPSAiTWF4aW11bSBkZXB0aCAobSkiLCAKICAgICAgIHkgPSAiRGl2ZSBkdXJhdGlvbiAocykiLCAKICAgICAgIGNvbCA9ICJQaGFzZXMgb2YgdGhlIGRheSIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKPiBUaGVyZSBzZWVtcyB0byBiZSBhICpwYXRjaCogZm9yIGhpZ2ggZGVwdGhzIChlc3BlY2lhbGx5IHZpc2libGUgZm9yIGBpbmQyMDE4MDcwYCksIGJ1dCBJIGRvbid0IGtub3cgd2hhdCBpdCBjb3VsZCBiZSBsaW5rZWQgdG8uLi4KCiMjIERyaWZ0IFJhdGUKCj4gSW4gdGhlIGZvbGxvd2luZyBncmFwaHM6Cj4KPiAqIGBkcmlmdHJhdGVgIGlzIGNhbGN1bGF0ZWQgdXNpbmcgb25seSBgZGl2ZXR5cGUgPT0gIjI6IGRyaWZ0ImAKPiAqIHdoZXJlYXMgYWxsIHRoZSBvdGhlcnMgdmFyaWFibGVzIGFyZSBjYWxjdWxhdGVkIGFsbCBkaXZlcyBjb25zaWRlcmVkCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMjl9CiMgYnVpbGQgZGF0YXNldApkYXRhUGxvdCA8LSBkYXRhXzIwMThfZmlsdGVyW2RpdmV0eXBlID09ICIyOiBkcmlmdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZWRpYW4gZHJpZnQgcmF0ZSBmb3IgZHJpZnQgZGl2ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4oZHJpZnRyYXRlID0gbWVkaWFuKGRyaWZ0cmF0ZSwgbmEucm0gPSBUKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSkKXVtkYXRhXzIwMThfZmlsdGVyWywKICAgICAgICAgICAgICAgICAgIC4oCiAgICAgICAgICAgICAgICAgICAgICMgbWVkaWFuIGRpdmUgZHVyYXRpb24gYWxsIGRpdmVzIGNvbnNpZGVyZWQKICAgICAgICAgICAgICAgICAgICAgZGR1cmF0aW9uID0gbWVkaWFuKGRkdXJhdGlvbiwgbmEucm0gPSBUKSwKICAgICAgICAgICAgICAgICAgICAgIyBtZWRpYW4gbWF4IGRlcHRoIGFsbCBkaXZlcyBjb25zaWRlcmVkCiAgICAgICAgICAgICAgICAgICAgIG1heGRlcHRoID0gbWVkaWFuKG1heGRlcHRoLCBuYS5ybSA9IFQpLAogICAgICAgICAgICAgICAgICAgICAjIG1lZGlhbiBib3R0b20gZGl2ZXMgYWxsIGRpdmVzIGNvbnNpZGVyZWQKICAgICAgICAgICAgICAgICAgICAgYm90dHRpbWUgPSBtZWRpYW4oYm90dHRpbWUsIG5hLnJtID0gVCkKICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICBieSA9IC4oLmlkLCBkYXlfZGVwYXJ0dXJlKQpdLApvbiA9IGMoIi5pZCIsICJkYXlfZGVwYXJ0dXJlIikKXQpgYGAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zMCwgZmlnLmNhcD0iRHJpZnQgcmF0ZSB2cy4gQm90dG9tIHRpbWUifQojIHBsb3QKZ2dwbG90KGRhdGFQbG90LCBhZXMoeCA9IGJvdHR0aW1lLCB5ID0gZHJpZnRyYXRlLCBjb2wgPSAuaWQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjUpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKSArCiAgZmFjZXRfd3JhcCguaWQgfiAuKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgNzAwKSkgKwogIGxhYnMoeCA9ICJEYWlseSBtZWRpYW4gQm90dG9tIHRpbWUgKHMpIiwgCiAgICAgICB5ID0gIkRhaWx5IG1lZGlhbiBkcmlmdCByYXRlIChtLnMtMSkiKSArCiAgdGhlbWVfampvKCkKYGBgCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzEsIGZpZy5jYXA9IkRyaWZ0IHJhdGUgdnMuIE1heGltdW0gZGVwdGgifQojIHBsb3QKZ2dwbG90KGRhdGFQbG90LCBhZXMoeCA9IG1heGRlcHRoLCB5ID0gZHJpZnRyYXRlLCBjb2wgPSAuaWQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjUpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKSArCiAgZmFjZXRfd3JhcCguaWQgfiAuKSArCiAgbGFicyh4ID0gIkRhaWx5IG1lZGlhbiBNYXhpbXVtIGRlcHRoIChtKSIsIAogICAgICAgeSA9ICJEYWlseSBtZWRpYW4gZHJpZnQgcmF0ZSAobS5zLTEpIikgKwogIHRoZW1lX2pqbygpCmBgYAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTMyLCBmaWcuY2FwPSJEcmlmdCByYXRlIHZzLiBEaXZlIGR1cmF0aW9uIn0KIyBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKHggPSBkZHVyYXRpb24sIHkgPSBkcmlmdHJhdGUsIGNvbCA9IC5pZCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAuNSwgYWxwaGEgPSAuNSkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsKICBndWlkZXMoY29sb3IgPSAibm9uZSIpICsKICBmYWNldF93cmFwKC5pZCB+IC4pICsKICBsYWJzKHggPSAiRGFpbHkgbWVkaWFuIERpdmUgZHVyYXRpb24gKHMpIiwgCiAgICAgICB5ID0gIkRhaWx5IG1lZGlhbiBkcmlmdCByYXRlIChtLnMtMSkiKSArCiAgdGhlbWVfampvKCkKYGBgCgojIyBCZWhhdmlvcmFsIEFlcm9iaWMgRGl2ZSBMaW1pdCAoYkFETCkKCiMjIyBbQ29vayBldCBhbCAoMjAwOCldKGh0dHBzOi8vd3d3LnNjaWVuY2VkaXJlY3QuY29tL3NjaWVuY2UvYXJ0aWNsZS9waWkvUzAwMDMzNDcyMDgwMDEzNlg/dmlhJTNEaWh1YikKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zMywgZmlnLmNhcD0iUG9zdC1kaXZlIGR1cmF0aW9uIHZzLiBkaXZlIGR1cmF0aW9uIn0KIyBkaXZlIGR1cmF0aW9uIHZzIHBkaSBieSBkYXlzCmdncGxvdChkYXRhID0gZGF0YV8yMDE4X2ZpbHRlcltwZGkgPCAzMDAsIF0sIGFlcygKICB4ID0gZGR1cmF0aW9uLAogIHkgPSBwZGksCiAgY29sb3IgPSAuaWQsCiAgZ3JvdXAgPSBkZHVyYXRpb24sCiAgZmlsbCA9ICJub25lIgopKSArCiAgZ2VvbV9ib3hwbG90KHNob3cubGVnZW5kID0gRkFMU0UsIG91dGxpZXIuYWxwaGEgPSAwLjA1LCBhbHBoYSA9IDApICsKICBsYWJzKHggPSAiRGl2ZSBkdXJhdGlvbiAocykiLCB5ID0gIlBvc3QtZGl2ZSBkdXJhdGlvbiAocykiKSArCiAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHRoZW1lX2pqbygpCmBgYAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTM0LCBmaWcuY2FwPSJQb3N0LWRpdmUgZHVyYXRpb24gdnMuIGRpdmUgZHVyYXRpb24gKHJhdyBkYXRhKSJ9CiMgZGl2ZSBkdXJhdGlvbiB2cyBwZGkgYnkgZGF5cwpnZ3Bsb3QoZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbcGRpIDwgMzAwLF0sIGFlcyh4ID0gZGR1cmF0aW9uLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHBkaSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gLmlkKSkgKwogIGdlb21fcG9pbnQoc2hvdy5sZWdlbmQgPSBGQUxTRSwgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9zbW9vdGgoCiAgICBtZXRob2QgPSAiZ2FtIiwKICAgIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICBjb2wgPSAiYmxhY2siLAogICAgbGluZXR5cGUgPSAiZGFzaGVkIgogICkgKwogIGxhYnMoeCA9ICJEaXZlIGR1cmF0aW9uIChzKSIsIHkgPSAiUG9zdC1kaXZlIGR1cmF0aW9uIChzKSIpICsKICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgdGhlbWVfampvKCkKYGBgCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zNSwgZmlnLmNhcD0iUG9zdC1kaXZlIGR1cmF0aW9uIC8gZGl2ZSBkdXJhdGlvbiByYXRpbyB2cy4gZGF5IHNpbmNlIGRlcGFydHVyZSJ9CiMgZGl2ZSBkdXJhdGlvbiB2cyBwZGkgYnkgZGF5cwpnZ3Bsb3QoCiAgZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbcGRpIDwgMzAwLCAuKC5pZCwgcGRpX3JhdGlvID0gcGRpIC8gZGR1cmF0aW9uLCBkYXlfZGVwYXJ0dXJlKV0sCiAgYWVzKAogICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICB5ID0gcGRpX3JhdGlvLAogICAgY29sb3IgPSAuaWQsCiAgICBncm91cCA9IGRheV9kZXBhcnR1cmUsCiAgICBmaWxsID0gIm5vbmUiCiAgKQopICsKICBnZW9tX2JveHBsb3Qoc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgICAgICAgb3V0bGllci5hbHBoYSA9IDAuMDUsCiAgICAgICAgICAgICAgIGFscGhhID0gMCkgKwogIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9ICJQb3N0LWRpdmUgLyBEaXZlIGR1cmF0aW9uIHJhdGlvIikgKwogIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWVfeCIpICsKICAjIHpvb20KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMCwgMC40KSkgKwogIHRoZW1lX2pqbygpCmBgYAoKIyMjIFtTaGVybyBldCAqYWwuKiAoMjAxOCldKGh0dHBzOi8vd3d3LnJlc2VhcmNoZ2F0ZS5uZXQvcHVibGljYXRpb24vMjIyNjgzMDQyX1RvX2JyZWF0aGVfb3Jfbm90X3RvX2JyZWF0aGVfT3B0aW1hbF9icmVhdGhpbmdfYWVyb2JpY19kaXZlX2xpbWl0X2FuZF9veHlnZW5fc3RvcmVzX2luX2RlZXAtZGl2aW5nX2JsdWUtZXllZF9zaGFncykKCkJhc2VkIG9uIFtTaGVybyBldCAqYWwuKiAoMjAxOCldKGh0dHBzOi8vd3d3LnJlc2VhcmNoZ2F0ZS5uZXQvcHVibGljYXRpb24vMjIyNjgzMDQyX1RvX2JyZWF0aGVfb3Jfbm90X3RvX2JyZWF0aGVfT3B0aW1hbF9icmVhdGhpbmdfYWVyb2JpY19kaXZlX2xpbWl0X2FuZF9veHlnZW5fc3RvcmVzX2luX2RlZXAtZGl2aW5nX2JsdWUtZXllZF9zaGFncyksIHdlIGRlY2lkZWQgdG8gbG9vayBhdCB0aGUgKmJBREwqIGFzIHRoZSA5NXRoIHBlcmNlbnRpbGUgb2YgZGl2ZSBkdXJhdGlvbiBlYWNoIGRheSwgZm9yIHRob3NlIHdpdGggJG4gXGdlcSA1MCQuIFRoaXMgdGhyZXNob2xkIHdhcyBjaG9zZW4gZm9sbG93aW5nIHRoaXMgZmlndXJlOgoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTM2LCBmaWcuY2FwPSJEaXN0cmlidXRpb24gb2YgdGhlIG51bWJlciBvZiBkaXZlcyBlYWNoIGRheS4gVGhlIHRocmVzaG9sZCB1c2VkIHRvIGNhbGN1bGF0ZSBiQURMIGlzIGZpeGVkIGF0IDUwIGRpdmVzIHBlciBkYXkuIiwgZmlnLmhlaWdodD0zfQpnZ3Bsb3QoZGF0YV8yMDE4X2ZpbHRlclssLihuYl9kaXZlcyA9IC5OKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUpXSwgCiAgICAgICBhZXMoeD1uYl9kaXZlcywgZmlsbD0uaWQpKSArCiAgZ2VvbV9oaXN0b2dyYW0oc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBmYWNldF9ncmlkKC5+LmlkKSArCiAgbGFicyh5PSIjIG9mIGRheXMiLCB4ID0gIiMgb2YgZGl2ZXMgcGVyIGRheSIpICsKICB0aGVtZV9qam8oKQpgYGAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zNywgZmlnLmNhcD0iQmVoYXZpb3JhbCBBREwgdnMuIGRyaWZ0IHJhdGUgYWxvbmcgYW5pbWFscycgdHJpcCAoQW0gSSB0aGUgb25seSBvbmUgc2VlaW5nIHNvbWUga2luZCBvZiByZWxhdGlvbnNoaXA/KSJ9CiMgc2VsZWN0IGRheSB0aGF0IGhhdmUgYXQgbGVhc3QgNTAgZGl2ZXMKZGF5c190b19rZWVwID0gZGF0YV8yMDE4X2ZpbHRlclssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLihuYl9kaXZlcyA9IC5OKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IC4oLmlkLCBkYXlfZGVwYXJ0dXJlKV0gJT4lCiAgLltuYl9kaXZlcyA+PSA1MCxdCgojIGtlZXAgb25seSB0aG9zZSBkYXlzCmRhdGFfMjAxOF9maWx0ZXJfY29tcGxldGVfZGF5ID0gbWVyZ2UoZGF0YV8yMDE4X2ZpbHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlzX3RvX2tlZXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpKQoKIyBkYXRhIHBsb3QKZGF0YVBsb3QgPSBkYXRhXzIwMThfZmlsdGVyX2NvbXBsZXRlX2RheVtkaXZldHlwZT09IjE6IGZvcmFnaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKGJhZGwgPSBxdWFudGlsZShkZHVyYXRpb24sIDAuOTUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IC4oLmlkLCBkYXlfZGVwYXJ0dXJlKV0KCiMgY29tYmluZSB0d28gZGF0YXNldHMgdG8gYmUgYWJsZSB0byB1c2UgYSBzZWNvbmQgYXhpcwojIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQ5MTg1NTgzL3R3by15LWF4ZXMtd2l0aC1kaWZmZXJlbnQtc2NhbGVzLWZvci10d28tZGF0YXNldHMtaW4tZ2dwbG90MgpkYXRhTWVnYVBsb3QgPSByYmluZChkYXRhXzIwMThfZmlsdGVyX2NvbXBsZXRlX2RheVtkaXZldHlwZSA9PSAiMjogZHJpZnQiXSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAuWywgLih3ID0gLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBkcmlmdHJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeiA9ICJzZWNvbmRfcGxvdCIpXSwKICAgICAgICAgICAgICAgICAgICAgZGF0YVBsb3RbLCAuKAogICAgICAgICAgICAgICAgICAgICAgIHcgPSAuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIyB0cmlja3kgb25lCiAgICAgICAgICAgICAgICAgICAgICAgeSA9IChiYWRsIC8gMTAwMCkgLSAxLAogICAgICAgICAgICAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICAgICAgICAgICAgIHogPSAiZmlyc3RfcGxvdCIKICAgICAgICAgICAgICAgICAgICAgKV0pCgojIHBsb3QKZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoCiAgICBkYXRhID0gZGF0YU1lZ2FQbG90W3ogPT0gInNlY29uZF9wbG90IiwgXSwKICAgIGFlcyh4ID0geCwgeSA9IHkpLAogICAgYWxwaGEgPSAxIC8gMTAsCiAgICBzaXplID0gMC41LAogICAgY29sb3IgPSAiZ3JleTQwIiwKICAgIHNob3cubGVnZW5kID0gRkFMU0UKICApICsKICBnZW9tX3BhdGgoZGF0YSA9IGRhdGFNZWdhUGxvdFt6ID09ICJmaXJzdF9wbG90IiwgXSwKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSB3KSwKICAgICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgICMgRmVhdHVyZXMgb2YgdGhlIGZpcnN0IGF4aXMKICAgIG5hbWUgPSAiRHJpZnQgcmF0ZSAobS9zKSIsCiAgICAjIEFkZCBhIHNlY29uZCBheGlzIGFuZCBzcGVjaWZ5IGl0cyBmZWF0dXJlcwogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyggfiAoLiAqIDEwMDApICsgMTAwMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkJlaGF2aW9yYWwgQWVyb2JpYyBEaXZlIExpbWl0IChzKSIpCiAgKSArCiAgbGFicyh4ID0gIiMgZGF5cyBzaW5jZSBkZXBhcnR1cmUiKSArCiAgZmFjZXRfd3JhcCh3IH4gLikgKwogIHRoZW1lX2pqbygpCmBgYAoKPiBMb29raW5nIGF0IHRoaXMgZ3JhcGgsIEkgd2FudCB0byBiZWxpZXZlIHRoYXQgdGhlcmUgaXMgc29tZSBraW5kIG9mIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSAqYkFETCogYXMgZGVmaW5lZCBieSBbU2hlcm8gZXQgKmFsLiogKDIwMTgpXShodHRwczovL3d3dy5yZXNlYXJjaGdhdGUubmV0L3B1YmxpY2F0aW9uLzIyMjY4MzA0Ml9Ub19icmVhdGhlX29yX25vdF90b19icmVhdGhlX09wdGltYWxfYnJlYXRoaW5nX2Flcm9iaWNfZGl2ZV9saW1pdF9hbmRfb3h5Z2VuX3N0b3Jlc19pbl9kZWVwLWRpdmluZ19ibHVlLWV5ZWRfc2hhZ3MpIGFuZCB0aGUgZHJpZnQgcmF0ZSAoYW5kIHNvIGJ1eW9hbmN5KS4KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zOH0KIyBnZXQgYmFkbApkYXRhcGxvdF8xID0gZGF0YV8yMDE4X2ZpbHRlcl9jb21wbGV0ZV9kYXlbLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKGJhZGwgPSBxdWFudGlsZShkZHVyYXRpb24sIDAuOTUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSldCiMgZ2V0IGRyaWZ0cmF0ZQpkYXRhcGxvdF8yID0gZGF0YV8yMDE4X2ZpbHRlcl9jb21wbGV0ZV9kYXlbZGl2ZXR5cGUgPT0gIjI6IGRyaWZ0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLihkcmlmdHJhdGUgPSBtZWRpYW4oZHJpZnRyYXRlKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUpXQoKIyBtZXJnZQpkYXRhUGxvdCA9IG1lcmdlKGRhdGFwbG90XzEsCiAgICAgICAgICAgICAgICAgZGF0YXBsb3RfMiwKICAgICAgICAgICAgICAgICBieSA9IGMoIi5pZCIsICJkYXlfZGVwYXJ0dXJlIiksCiAgICAgICAgICAgICAgICAgYWxsID0gVFJVRSkKCiMgcGxvdApnZ3Bsb3QoZGF0YSA9IGRhdGFQbG90LCBhZXMoeCA9IGJhZGwsIHkgPSBkcmlmdHJhdGUsIGNvbCA9IC5pZCkpICsKICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRkFMU0UpICsKICBmYWNldF93cmFwKC5pZH4uLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9qam8oKQpgYGAKCiMjIyB7LnVubGlzdGVkIC51bm51bWJlcmVkIC50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CgojIyMjIGluZF8yMDE4MDcwIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzl9CiMgaW5kXzIwMTgwNzAKcGxvdF9seSgKICB4ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3MCIsIGJhZGxdLAogIHkgPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDcwIiwgZGF5X2RlcGFydHVyZV0sCiAgeiA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzAiLCBkcmlmdHJhdGVdLAogIHR5cGUgPSAic2NhdHRlcjNkIiwKICBtb2RlID0gIm1hcmtlcnMiLAogIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDIpLAogIGNvbG9yID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3MCIsIGRheV9kZXBhcnR1cmVdCikgJT4lIAogIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0JlaGF2aW9yYWwgQURMJyksCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnIyBkYXlzIHNpbmNlIGRlcGFydHVyZScpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJ0RyaWZ0IHJhdGUgKG0vcyknKSkpCmBgYAoKIyMjIyBpbmRfMjAxODA3MiB7LnVubGlzdGVkIC51bm51bWJlcmVkfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTQwfQojIGluZF8yMDE4MDcyCnBsb3RfbHkoCiAgeCA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzIiLCBiYWRsXSwKICB5ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3MiIsIGRheV9kZXBhcnR1cmVdLAogIHogPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDcyIiwgZHJpZnRyYXRlXSwKICB0eXBlID0gInNjYXR0ZXIzZCIsCiAgbW9kZSA9ICJtYXJrZXJzIiwKICBtYXJrZXIgPSBsaXN0KHNpemUgPSAyKSwKICBjb2xvciA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzIiLCBkYXlfZGVwYXJ0dXJlXQopICU+JSAKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICdCZWhhdmlvcmFsIEFETCcpLAogICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJyMgZGF5cyBzaW5jZSBkZXBhcnR1cmUnKSwKICAgICAgICAgICAgICAgICAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICdEcmlmdCByYXRlIChtL3MpJykpKQpgYGAKCiMjIyMgaW5kXzIwMTgwNzQgey51bmxpc3RlZCAudW5udW1iZXJlZH0KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC00MX0KIyBpbmRfMjAxODA3NApwbG90X2x5KAogIHggPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDc0IiwgYmFkbF0sCiAgeSA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzQiLCBkYXlfZGVwYXJ0dXJlXSwKICB6ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3NCIsIGRyaWZ0cmF0ZV0sCiAgdHlwZSA9ICJzY2F0dGVyM2QiLAogIG1vZGUgPSAibWFya2VycyIsCiAgbWFya2VyID0gbGlzdChzaXplID0gMiksCiAgY29sb3IgPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDc0IiwgZGF5X2RlcGFydHVyZV0KKSAlPiUgCiAgbGF5b3V0KHNjZW5lID0gbGlzdCh4YXhpcyA9IGxpc3QodGl0bGUgPSAnQmVoYXZpb3JhbCBBREwnKSwKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICcjIGRheXMgc2luY2UgZGVwYXJ0dXJlJyksCiAgICAgICAgICAgICAgICAgICAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAnRHJpZnQgcmF0ZSAobS9zKScpKSkKYGBgCgojIyMjIGluZF8yMDE4MDcyIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNDJ9CiMgaW5kXzIwMTgwODAKcGxvdF9seSgKICB4ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA4MCIsIGJhZGxdLAogIHkgPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDgwIiwgZGF5X2RlcGFydHVyZV0sCiAgeiA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwODAiLCBkcmlmdHJhdGVdLAogIHR5cGUgPSAic2NhdHRlcjNkIiwKICBtb2RlID0gIm1hcmtlcnMiLAogIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDIpLAogIGNvbG9yID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA4MCIsIGRheV9kZXBhcnR1cmVdCikgJT4lIAogIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0JlaGF2aW9yYWwgQURMJyksCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnIyBkYXlzIHNpbmNlIGRlcGFydHVyZScpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJ0RyaWZ0IHJhdGUgKG0vcyknKSkpCmBgYAoKIyMgR1BTIGRhdGEKClNpbmNlIHRoaXMgcGFydCBpcyB0aW1lIGNvbnN1bWluZywgd2UgZGVkaWNhdGVkIGEgd2hvbGUgYXJ0aWNsZSAoYHZpZ25ldHRlKCJkYXRhX2V4cGxvcmF0aW9uXzIwMThfbWFwIilgKSB0byByZWR1Y2UgY29tcGlsYXRpb24gdGltZS4KCmBgYHtyfQojIHNhdmluZyB0aGUgZGF0YV8yMDE4X2ZpbHRlciBkYXRhc2V0CnNhdmVSRFMoZGF0YV8yMDE4X2ZpbHRlciwgZmlsZSA9ICJ0bXAvZGF0YV8yMDE4X2ZpbHRlci5yZHMiKQpgYGAKCg==